import flash.display.Graphics;
import flash.events.Event;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import fl.motion.Color;
import flash.geom.ColorTransform;
import flash.events.MouseEvent;

/*[Embed(source="song")]
var song1:Class;*/

//var snd:Sound = new song1() as Sound;

//Public Variables
var lastY:int = 0;
var lastX:int = 0;
var lastVolR:Number = 0;
var lastGainR:Number = 0;
var volCenterX:int;
var volCenterY:int;
var gainCenterX:int;
var gainCenterY:int;
var numSounds:int = 20;
var i:int;
var gainLevel:Number = 0.5;
var track:int;

//Graph Variables
const waveX:int = 30;
const waveY:int = 420;
const PLOT_HEIGHT:int = 100;//200
const CHANNEL_LENGTH:int = 250;
var bytes:ByteArray = new ByteArray();

//Sound Loading
var channels:Array = new Array();
for(i=0; i<numSounds; i++){
	channels.push(new SoundChannel);
}
var snd1:Sound = new Sound();
var req:URLRequest = new URLRequest("Sine.mp3");
snd1.load(req);
var snd2:Sound = new Sound();
var req2:URLRequest = new URLRequest("Dist_guitar.mp3");
snd2.load(req2);

for(i=0; i<numSounds; i++){
	track = 2;
	channels[i] = snd2.play();
}

//initialization of variables
gainKnob.rotation = -149;
lastGainR = gainKnob.rotation;
volCenterX = volBox.x;
volCenterY = volBox.y;
gainCenterX = gainBox.x;
gainCenterY = gainBox.y;
onButton1.visible = false;
onButton2.visible = true;
offButton1.visible = true;
offButton2.visible = false;
changeGain();

channels[0].addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
nutBox1.addEventListener(MouseEvent.CLICK, flipSwitch1);
nutBox2.addEventListener(MouseEvent.CLICK, flipSwitch2);
volBox.addEventListener(MouseEvent.MOUSE_DOWN, onVolDown);
gainBox.addEventListener(MouseEvent.MOUSE_DOWN, onGainDown);
addEventListener(Event.ENTER_FRAME, drawGraph);

//Sound Change Function=================================================================

function onPlaybackComplete(event:Event):void{
	changeSound();
}
function changeSound():void{
	SoundMixer.stopAll();
	channels[0].removeEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
	if(track == 1){
		for(i=0; i<numSounds; i++){
			channels[i] = snd1.play();
		}
		changeGain();
	}else if(track == 2){
		for(i=0; i<numSounds; i++){
			channels[i] = snd2.play();
		}
		changeGain();
	}
	channels[0].addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
}
function flipSwitch1(event:Event):void{
	if(offButton1.visible == true){
		offButton1.visible = false;
		onButton1.visible = true;
		if(onButton2.visible == true){
			onButton2.visible = false;
			offButton2.visible = true;
		}
		track = 1;
		changeSound();
	}else{
		offButton1.visible = true;
		onButton1.visible = false;
		SoundMixer.stopAll();
	}
}

function flipSwitch2(event:Event):void{
	if(offButton2.visible == true){
		offButton2.visible = false;
		onButton2.visible = true;
		if(onButton1.visible == true){
			onButton1.visible = false;
			offButton1.visible = true;
		}
		track = 2;
		changeSound();
	}else{
		offButton2.visible = true;
		onButton2.visible = false;
		SoundMixer.stopAll();
	}
}

//Volume and Gain change functions=====================================================
function changeGain():void{
	var gintOn:int = (lastGainR + 150)/(300/numSounds);
	var gdisplay:int = gintOn/1.9;
	gainLevel = (lastGainR + 150)/300;
	if(gainLevel < (1/numSounds)){
		gainLevel = 1/numSounds;
	}
	gainText.text = "";
	gainText.text += gdisplay;
	changeVolume();
}

function changeVolume():void{
	var intOn:int = (lastVolR + 150)/(300/numSounds);
	var fracOn:Number = (lastVolR + 150)/(300/numSounds) - intOn;
	var numOn:Number = intOn;
	var vdisplay:int = intOn/1.9;
	/*cout.text = "";
	cout.text += numOn;*/
	volText.text = "";
	volText.text += vdisplay;
	
	var volLevel = channels[0].soundTransform;
	var zeroVolLevel = channels[0].soundTransform;
	var fracVolLevel = channels[0].soundTransform;
	var newLevel:Number = gainLevel;
	var fracLevel:Number = gainLevel * fracOn;
	var zeroLevel:Number = 0.0;
	volLevel.volume = newLevel;
	zeroVolLevel.volume = zeroLevel;
	fracVolLevel.volume = fracLevel;
	for(i=0; i<numSounds; i++){
		if(i < numOn){
			channels[i].soundTransform = volLevel;
		}else if(i == numOn){
			channels[i].soundTransform = fracVolLevel;
		}else{
			channels[i].soundTransform = zeroVolLevel;
		}
	}
}
//ON ENTER FRAME draw graph function=====================================================
function drawGraph(event:Event):void{
	SoundMixer.computeSpectrum(bytes, false, 0);
    var g:Graphics = this.graphics;
    var n:Number = 0;
	
    g.clear();
    g.lineStyle(0, 0x6600CC);
    g.beginFill(0x6600CC, 0.4);
    g.moveTo(waveX, waveY);
    
    // left channel===============================================
    for (var i:int = 0; i < CHANNEL_LENGTH; i++) 
    {
        n = (bytes.readFloat() * (PLOT_HEIGHT));
        g.lineTo(waveX+(i * 3), (waveY - n));
		if(Math.abs(PLOT_HEIGHT - n) < 12 || Math.abs((-PLOT_HEIGHT)+n) < 12){
			lightOff.visible = false;
			lightBackOff.visible = false;
		}else{
			lightOff.visible = true;
			lightBackOff.visible = true;
		}
    }
    g.lineTo(CHANNEL_LENGTH * 3 + waveX, waveY);
    g.endFill();
	
	// top bar threshold============================
	g.lineStyle(3,0x000000,0.5);
	for(i = 0; i < CHANNEL_LENGTH * 3; i += 10){
    	g.moveTo(waveX+i, waveY-PLOT_HEIGHT);
		g.lineTo(waveX+i+4,waveY-PLOT_HEIGHT);
	}
	
	// bottom bar threshold=========================
	g.lineStyle(3,0x000000,0.5);
	for(i = 0; i < CHANNEL_LENGTH * 3; i += 10){
    	g.moveTo(waveX+i, waveY+PLOT_HEIGHT);
		g.lineTo(waveX+i+4,waveY+PLOT_HEIGHT);
	}
}


//volume knob mouse events==========================================================================
function onVolDown(event:MouseEvent):void{
	addEventListener(MouseEvent.MOUSE_MOVE, onVolMove);
	addEventListener(MouseEvent.MOUSE_UP, onVolUp);
	lastY = event.stageY;
	lastX = event.stageX;
	var hypo:Number;
	var rotat:Number;
	var xdist:Number;
	var centerX:int = volCenterX;
	var centerY:int = volCenterY;
	
	hypo = Math.sqrt(Math.pow((lastX - centerX),2) + Math.pow((lastY-centerY),2));
	xdist = Math.abs(lastX - centerX);
	
	if(lastX > centerX && lastY < centerY){
		rotat = Math.asin(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY < centerY){
		rotat = -(Math.asin(xdist/hypo)/(Math.PI/180));
	}else if(lastX > centerX && lastY > centerY){
		rotat = 90 + Math.acos(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY > centerY){
		rotat = (-90) + -(Math.acos(xdist/hypo)/(Math.PI/180));
	}else if(lastY == centerY && lastX < centerX){
		rotat = -90;
	}else if(lastY == centerY && lastX > centerX){
		rotat = 90;
	}
	
	if(rotat > (-150) && rotat < 150){
		volKnob.rotation = rotat;
		lastVolR = volKnob.rotation;
		changeVolume();
	}
}

function onVolUp(event:MouseEvent):void{
	//removeEventListener(MouseEvent.MOUSE_UP, onVolUp);
	removeEventListener(MouseEvent.MOUSE_MOVE, onVolMove);
	volBox.addEventListener(MouseEvent.MOUSE_DOWN, onVolDown);
}

function onVolMove(event:MouseEvent):void{
	lastY = event.stageY;
	lastX = event.stageX;
	var hypo:Number;
	var rotat:Number;
	var xdist:Number;
	var centerX:int = volCenterX;
	var centerY:int = volCenterY;
	
	hypo = Math.sqrt(Math.pow((lastX - centerX),2) + Math.pow((lastY-centerY),2));
	xdist = Math.abs(lastX - centerX);
	
	if(lastX > centerX && lastY < centerY){
		rotat = Math.asin(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY < centerY){
		rotat = -(Math.asin(xdist/hypo)/(Math.PI/180));
	}else if(lastX > centerX && lastY > centerY){
		rotat = 90 + Math.acos(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY > centerY){
		rotat = (-90) + -(Math.acos(xdist/hypo)/(Math.PI/180));
	}else if(lastY == centerY && lastX < centerX){
		rotat = -90;
	}else if(lastY == centerY && lastX > centerX){
		rotat = 90;
	}
	
	if(rotat > (-150) && rotat < 150){
		if(!((lastVolR > 130 && rotat <= 0)||(lastVolR < (-130) && rotat >= 0))){
			volKnob.rotation = rotat;
			lastVolR = volKnob.rotation;
			changeVolume();
		}
	}
}

//gain knob mouse events==========================================================================
function onGainDown(event:MouseEvent):void{
	addEventListener(MouseEvent.MOUSE_MOVE, onGainMove);
	addEventListener(MouseEvent.MOUSE_UP, onGainUp);
	lastY = event.stageY;
	lastX = event.stageX;
	var hypo:Number;
	var rotat:Number;
	var xdist:Number;
	var centerX:int = gainCenterX;
	var centerY:int = gainCenterY;
	
	hypo = Math.sqrt(Math.pow((lastX - centerX),2) + Math.pow((lastY-centerY),2));
	xdist = Math.abs(lastX - centerX);
	
	if(lastX > centerX && lastY < centerY){
		rotat = Math.asin(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY < centerY){
		rotat = -(Math.asin(xdist/hypo)/(Math.PI/180));
	}else if(lastX > centerX && lastY > centerY){
		rotat = 90 + Math.acos(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY > centerY){
		rotat = (-90) + -(Math.acos(xdist/hypo)/(Math.PI/180));
	}else if(lastY == centerY && lastX < centerX){
		rotat = -90;
	}else if(lastY == centerY && lastX > centerX){
		rotat = 90;
	}
	
	if(rotat > (-150) && rotat < 150){
		gainKnob.rotation = rotat;
		lastGainR = gainKnob.rotation;
/*		cout.text = "";
		cout.text += rotat;*/
		changeGain();
	}
}

function onGainUp(event:MouseEvent):void{
	//removeEventListener(MouseEvent.MOUSE_UP, onGainUp);
	removeEventListener(MouseEvent.MOUSE_MOVE, onGainMove);
	gainBox.addEventListener(MouseEvent.MOUSE_DOWN, onGainDown);
}

function onGainMove(event:MouseEvent):void{
	lastY = event.stageY;
	lastX = event.stageX;
	var hypo:Number;
	var rotat:Number;
	var xdist:Number;
	var centerX:int = gainCenterX;
	var centerY:int = gainCenterY;
	
	hypo = Math.sqrt(Math.pow((lastX - centerX),2) + Math.pow((lastY-centerY),2));
	xdist = Math.abs(lastX - centerX);
	
	if(lastX > centerX && lastY < centerY){
		rotat = Math.asin(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY < centerY){
		rotat = -(Math.asin(xdist/hypo))/(Math.PI/180);
	}else if(lastX > centerX && lastY > centerY){
		rotat = 90 + Math.acos(xdist/hypo)/(Math.PI/180);
	}else if(lastX < centerX && lastY > centerY){
		rotat = (-90) + -(Math.acos(xdist/hypo))/(Math.PI/180);
	}else if(lastY == centerY && lastX < centerX){
		rotat = -90;
	}else if(lastY == centerY && lastX > centerX){
		rotat = 90;
	}
	
	if(rotat > (-150) && rotat < 150){
		if(!((lastGainR > 130 && rotat <= 0)||(lastGainR < (-130) && rotat >= 0))){
			gainKnob.rotation = rotat;
			lastGainR = gainKnob.rotation;
			/*cout.text = "";
			cout.text += rotat;*/
			changeGain();
		}
	}
}